import { useState, useCallback } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { Field, Form, Formik } from 'formik'
import useClipboard from 'react-use-clipboard'
import { UsageEnvironment } from '@prisma/client'
import IVInputField from '~/components/IVInputField'
import IVButton from '~/components/IVButton'
import { trpc } from '~/utils/trpc'
import IVSpinner from '~/components/IVSpinner'
import PageHeading from '~/components/PageHeading'
import { notify } from '~/components/NotificationCenter'
import useDashboard, { useHasPermission } from '~/components/DashboardContext'
import ApiKeyButton from '~/components/APIKeyButton'
import { useEffect } from 'react'
import Dialog, { useDialogState } from '~/components/IVDialog'
import IconClipboard from '~/icons/compiled/Clipboard'
import KeysList from '~/components/KeysList'
import IVAlert from '~/components/IVAlert'
import IconInfo from '~/icons/compiled/Info'
import IVSelect from '~/components/IVSelect'
import { DEVELOPMENT_ORG_ENV_SLUG } from '~/utils/environments'
function DevKeySelector() {
const ctx = trpc.useContext()
const regenerate = trpc.useMutation('key.regenerate', {
onSuccess() {
notify.success('API key regenerated')
ctx.invalidateQueries('key.dev')
},
})
const onRegenerate = useCallback(async () => {
if (
!window.confirm(
'Are you sure you want to regenerate your personal development key?'
)
)
return
regenerate.mutate()
}, [regenerate])
return (
)
}
export default function KeysPage() {
const navigate = useNavigate()
const { me, organization } = useDashboard()
const devPermission = useHasPermission('CREATE_DEV_API_KEYS')
const prodPermission = useHasPermission('CREATE_PROD_API_KEYS')
const createKeyDialog = useDialogState()
const [newToken, setNewToken] = useState(null)
const keys = trpc.useQuery(['key.prod', { organizationId: organization.id }])
const { refetch: refetchKeys } = keys
const { visible: keyDialogVisible, animating: keyDialogAnimating } =
createKeyDialog
useEffect(() => {
if (!keyDialogVisible) {
refetchKeys()
}
}, [keyDialogVisible, refetchKeys])
useEffect(() => {
if (!keyDialogVisible && !keyDialogAnimating) {
setNewToken(null)
}
}, [keyDialogVisible, keyDialogAnimating])
const onCreateKey = useCallback(
(token: string) => {
setNewToken(token)
refetchKeys()
},
[refetchKeys]
)
if (prodPermission === false && devPermission === false) {
navigate('/dashboard')
return
}
return (
API keys are used to authenticate your account within the SDK and link
your actions to your Interval dashboard.
Personal development key
Use this key to develop actions. When an app is started with this key,
its actions will appear in the{' '}
Development environment
.
Live mode keys
{prodPermission ? (
Create live keys when you're ready to{' '}
deploy your actions
{' '}
and make them accessible to your organization.
) : (
You don't have permission to create or manage live keys.
)}
{prodPermission && (
)}
{prodPermission && (
<>
{keys.data?.length ? (
) : (
{me.isEmailConfirmationRequired ? (
Confirm your email to create live keys.
) : (
{!keys.isLoading && 'You do not have any live mode keys.'}
)}
)}
>
)}
)
}
function InlineCopyKeyButton({ token }: { token: string }) {
const [isCopied, setCopied] = useClipboard(token, {
successDuration: 3000,
})
useEffect(() => {
if (isCopied) {
notify.success('Copied token to clipboard')
}
}, [isCopied])
return (
)
}
function CreateKeyForm({
usageEnvironment,
onSubmit,
}: {
usageEnvironment: UsageEnvironment
onSubmit?: (token: string) => void
}) {
const createKey = trpc.useMutation('key.add')
const { organization } = useDashboard()
const environments = organization.environments.filter(
e => e.slug !== DEVELOPMENT_ORG_ENV_SLUG
)
return (
initialValues={{
label: '',
organizationEnvironmentId: environments[0].id,
}}
onSubmit={async ({ label, organizationEnvironmentId }, { resetForm }) => {
if (createKey.isLoading) return
createKey.mutate(
{
label,
usageEnvironment,
organizationEnvironmentId,
},
{
onSuccess({ token }) {
resetForm()
notify.success(`Key '${label}' was created.`)
if (onSubmit) {
onSubmit(token)
}
},
}
)
}}
>
)
}